Alternate Screen Buffer
概要
切り替えシーケンス
code:_
代替スクリーンに切り替え + カーソル保存:
\x1b[?1049h
プライマリスクリーンに復帰 + カーソル復元:
\x1b[?1049l
歴史的なバリエーション(互換性のため知っておくべき):
\x1b[?47h / \x1b[?47l — 代替スクリーン (カーソル保存なし)
\x1b[?1047h / \x1b[?1047l — 代替スクリーン (画面クリア付き)
\x1b[?1048h / \x1b[?1048l — カーソル保存/復元のみ
\x1b[?1049h / \x1b[?1049l — 上記の組み合わせ (推奨)
実装上のポイント
code:_
vimの起動/終了で起こること:
1. vim起動時:
\x1b[?1049h ← 代替スクリーンに切り替え
\x1b[2J ← 画面クリア
\x1b[1;1H ← カーソルを左上に
... ファイル内容を描画 ...
2. vim終了時:
\x1b[?1049l ← プライマリスクリーンに復帰
→ vim起動前のシェル画面がそのまま復元される
code:rust
// 実装例(擬似コード)
struct Terminal {
primary_screen: Screen,
alternate_screen: Screen,
active_screen: ScreenType,
saved_cursor: Option<CursorState>,
}
fn handle_decset(&mut self, mode: u16) {
match mode {
1049 => {
// カーソル保存
self.saved_cursor = Some(self.cursor_state());
// 代替スクリーンに切り替え
self.active_screen = ScreenType::Alternate;
self.alternate_screen.clear();
}
_ => {}
}
}
fn handle_decrst(&mut self, mode: u16) {
match mode {
1049 => {
// プライマリスクリーンに復帰
self.active_screen = ScreenType::Primary;
// カーソル復元
if let Some(cursor) = self.saved_cursor.take() {
self.restore_cursor(cursor);
}
}
_ => {}
}
}